#include "sharedata.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QFile>
#include <QThread>
#include <QQuickItem>
#include <QQmlContext>


QmlShareData::QmlShareData(QObject *parent) : QObject(parent),
    m_qml_view_(nullptr),
    m_luavm_status_(false),
    m_network_(nullptr),
    m_tcp_server(nullptr)
{
    m_serial_controller_ = new SerialController(nullptr);
    QFile file("Test.lua");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QTextStream in(&file);
    m_lua_string = in.readAll();
    int ret = m_lua_.DoString(m_lua_string);
    if(ret < 0){
        qDebug()<<"默认lua脚本加载错误";
    }else{
        m_luavm_status_ = true;
    }
}

int QmlShareData::SetQuickView(QQuickWidget *view)
{
    QStringList comList;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos) {
        comList<<info.portName();
    }
    // 设置qml基本属性
    this->m_qml_view_ = view;
    QObject *qmlObject = view->rootObject()->findChild<QObject*>("SerialSelect",
                                                   Qt::FindChildOption::FindChildrenRecursively);
    if(nullptr != qmlObject)
        qmlObject->setProperty("comlist",comList);
    m_qml_protodebug_ = view->rootObject()->findChild<QObject*>("ProtoDebug",
                                            Qt::FindChildOption::FindChildrenRecursively);

    if(nullptr != m_qml_protodebug_)
        m_qml_protodebug_->setProperty("lua_script_text",m_lua_string);

}


int QmlShareData::OnDataRecv(QByteArray arr)
{
    if(m_luavm_status_)
        m_lua_.OnSerialData(QString(arr));
}

int QmlShareData::ShowDataInQML(QString x)
{
    if(nullptr != m_qml_protodebug_){
        QMetaObject::invokeMethod(m_qml_protodebug_, "addString",Q_ARG(QVariant, x));
    }
}

int QmlShareData::SendUartData(const char *data)
{
    if(nullptr != data){
        this->m_serial_controller_->SendData((char *)data,strlen(data));
        return 0;
    }
    return -1;
}

int QmlShareData::openUart(QString port, QString baudRate, QString dataBits, QString stopBits, QString flow)
{
    if(m_serial_controller_->OpenSerial(port,baudRate,dataBits,stopBits,flow) == 0){
        m_serial_controller_->SetListener(this);
        return 0;
    }
    qDebug()<<"openserial failed";
    return -1;
}

int QmlShareData::openNetwork(QString ip, unsigned int port, bool is_ws,int type)
{
    if(type == NetworkController::TYPE_TCP_CLIENT){
        qDebug()<<"connect to server";
        if(m_network_ == nullptr)
            m_network_ = new NetworkController(NetworkController::TYPE_TCP_CLIENT,ip,port);
        else{
            delete m_network_;
            m_network_ = nullptr;
            m_network_ = new NetworkController(NetworkController::TYPE_TCP_CLIENT,ip,port);
        }
        connect(m_network_,SIGNAL(on_connected()),this,SLOT(on_network_conected()));
        connect(m_network_,SIGNAL(on_disconnectd()),this,SLOT(on_network_disconected()));
        connect(m_network_,SIGNAL(on_data_recv()),this,SLOT(on_network_data_recv()));
        return 0;
    }
    if((type == NetworkController::TYPE_UDP_CLIENT)  ||
            (type == NetworkController::TYPE_UDP_SERVER)){
        m_network_ = new NetworkController((NetworkController::NetworkType)type,ip,port);
        connect(m_network_,SIGNAL(on_data_recv()),this,SLOT(on_network_data_recv()));
        emit(sendToQml(11));

        return 0;
    }
    if(type ==  NetworkController::TYPE_TCP_SERVER){
        m_tcp_server = new TcpServerLibevent(port,ip.toStdString());
        m_tcp_server->StartServerAsync();
        m_tcp_server->moveToThread(this->thread());
        connect(m_tcp_server,SIGNAL(on_onnected(string , uint )),this,SLOT(on_network_conected(string , uint )),Qt::DirectConnection);
        connect(m_tcp_server,SIGNAL(on_disconected(string , uint )),this,SLOT(on_network_disconected(string , uint )),Qt::DirectConnection);
        connect(m_tcp_server,SIGNAL(on_conn_read(string )),this,SLOT(on_network_server_read(string)),Qt::DirectConnection);

        return 0;
    }
    return -1;
}

int QmlShareData::closeNetwork(QString type)
{
    if(type == "tcpserver"){
        if(nullptr != m_tcp_server){
            m_tcp_server->StopServer();
            delete m_tcp_server;
            m_tcp_server = nullptr;
        }
    }
    else
        m_network_->Close();

}

int QmlShareData::closeSerial()
{
    if(m_serial_controller_->CloseSerial() == 0){
        qDebug()<<"close serial ok";
        return 0;
    }
    qDebug()<<"cloase serial failed";
    return -1;
}

int QmlShareData::TestLua()
{
    m_lua_.OnSerialData("ceshi");
    return 0;
}

int QmlShareData::TestShowData()
{
    if(nullptr != m_qml_protodebug_){
        QMetaObject::invokeMethod(m_qml_protodebug_, "addString",Q_ARG(QVariant, QString("test\r\n")));
    }
    return 0;
}

int QmlShareData::updateLuaScript(QString str)
{
    qDebug()<<QThread::currentThreadId();
    m_lua_string = str;
    qDebug()<<str;
    int ret = m_lua_.UpdateScript(m_lua_string);
    if(ret < 0){
        qDebug()<<"更新lua脚本失败";
        m_luavm_status_ = false;
        return -1;
    }
    m_luavm_status_ = true;
    return 0;
}

int QmlShareData::saveLuaScript(QString s)
{
    QFile file("Test.lua");						//---打开文件
    if (file.open(QIODevice::WriteOnly) )
    {
        //-----将数据写入文件
        qint64 LineLen = file.write(s.toStdString().c_str(), s.size());
        if (LineLen <= 0)
        {
            return -1;
        }
    }
    file.close();
    return 0;
}

bool QmlShareData::luaStatus()
{
    return m_luavm_status_;
}

bool QmlShareData::DoLuaCmd(QString)
{

}

void QmlShareData::on_network_data_recv(){
    qDebug()<<"recv data";
    char dat[4096] = {0};
    auto ret = this->m_network_->ReadData((int8_t * )dat);
    qDebug()<<ret.len<<ret.addr;
    if(ret.len > 0){
        m_lua_.OnNetworkData((char*)ret.addr.toStdString().data(),dat,ret.port.toUInt());
    }
}

void QmlShareData::on_network_conected(string ip, uint port)
{
    m_lua_.OnNewTcpClient(QString::fromStdString(ip),port,0);
}

void QmlShareData::on_network_disconected(string ip, uint port)
{
    m_lua_.OnClientLeave(QString::fromStdString(ip),0,port);
}

void QmlShareData::on_udp_data_recv(){
    char dat[4096] = {0};
    auto ret = this->m_network_->ReadData((int8_t * )dat);
    qDebug()<<dat;
    if(ret.len > 0){
        m_lua_.OnNetworkData((char*)ret.addr.toStdString().data(),dat,ret.port.toUInt());
    }
}

void QmlShareData::on_network_server_read(string ip)
{
    qDebug()<<ip.c_str();
}





